#ifndef __EVENTLOOP_H__
#define __EVENTLOOP_H__
#include "TcpConnection.h"

#include <iostream>
#include <vector>
#include <map>
#include <memory>
#include <functional>
#include <mutex>

using std::mutex;
using std::function;
using std::shared_ptr;
using std::map;
using std::vector;

#include <sys/epoll.h>
class Acceptor;
class TcpConnection;
class EventLoop
{
    using TcpConnectionPtr = shared_ptr<TcpConnection>;
    using TcpConnectionCallback = function<void(const TcpConnectionPtr &)>;
    using Functor = function<void()>;
public:
    EventLoop();
    ~EventLoop();
    void loop();
    void unloop();

    void setMainLoop(Acceptor *acceptor);
    void removeConnection(const TcpConnectionPtr &conn)
    {
        _conns.erase(conn->fd());
    }
private:
    int createEpollFd();
    void addEpollReadFd(int fd); // acceptor监听新连接
    void delEpollReadFd(int fd);
    virtual void waitEpollFd();
    void handleMessage(int fd);
public:
    void handleNewConnection(int connfd); // acceptor处理新连接
    void setNewConnectionCallback(TcpConnectionCallback &&cb);
    void setMessageCallback(TcpConnectionCallback &&cb);
    void setCloseCallback(TcpConnectionCallback &&cb);
private:
    int createEventFd();
    void handleRead();
    void doPengdingFunctors();
public:
    void wakeup();
    void runInLoop(Functor &&cb);

private:
    int _epfd;
    vector<struct epoll_event> _evtList;
    bool _isLooping;
    // Acceptor &_acceptor;
    Acceptor *_acceptor;
    map<int, TcpConnectionPtr> _conns;

    TcpConnectionCallback _onNewConnection; // 主线程Reactor回调
    TcpConnectionCallback _onMessage;
    TcpConnectionCallback _onClose;

    int _evtfd;
    vector<Functor> _pengdings;
    mutex _mutex;

    bool _isMainLoop; // 是否是主Reactor
};

#endif


